package List;

import java.util.Iterator;

public class SortedList implements Iterable<PlayerNode> {
	
	PlayerNode naqHead;
	PlayerNode armyHead;
	PlayerNode head;
	PlayerNode current;
	
	public SortedList(){
		naqHead = new PlayerNode("start", 0);
		armyHead = new PlayerNode("start", 0);
		head = new PlayerNode("start", 0);
		current = armyHead;
	}
	
	public PlayerNode getLargestNaq(){		
		return naqHead.nextNaq;
	}
	
	public PlayerNode getLargestArmy(){
		return armyHead.nextArmy;
	}
	
	public void setNaq(int id, long n){
		for(Iterator<PlayerNode> p = iterateNaq(); p.hasNext(); )
		{
			PlayerNode temp = p.next();
			temp.lock();
			if(temp.getId() == id)
			{
				temp.setNaq(n);
			}
			try {
				temp.unlock();
			} catch (NodeNotLockedException e) {}
		}
	}
	
	public void setArmy(int id, int n){
		for(Iterator<PlayerNode> p = iterateNaq(); p.hasNext(); )
		{
			PlayerNode temp = p.next();
			temp.lock();
			if(temp.getId() == id)
			{
				temp.setArmySize(n);
			}
			try {
				temp.unlock();
			} catch (NodeNotLockedException e) {}
		}
	}
	
	public void addPlayer(PlayerNode n){
		PlayerNode prev;
		PlayerNode temp;
		/*if(n.getNaq() != 0 )//&& !contains)
		{
			n.next = head;
			head.next = n;
		}*/
		
		if(n.getNaq() != 0 )//&& !contains)
		{
			prev = naqHead;
			temp = naqHead.nextNaq;
			while(temp != null && temp.getNaq() >= n.getNaq()){
				prev = temp;
				temp = temp.nextNaq;
			}
			if(temp == null){
				prev.nextNaq = n;
			}
			else{
				prev.nextNaq = n;
				n.nextNaq = temp;
			}
		}
		
		if(n.getArmySize() != 0)//&& !contains)
		{
			prev = armyHead;
			temp = prev.nextArmy;
			while(temp != null && temp.compareTo(n) >= 0){
				prev = temp;
				temp = temp.nextArmy;
			}
			if(temp == null){
				prev.nextArmy = n;
			}
			else{
				prev.nextArmy = n;
				n.nextArmy = temp;
			}
		}
	}
	
	public Iterator<PlayerNode> iterateNaq() {
		naqHead.lock();
		return new Iterator<PlayerNode>() {
			PlayerNode prev = null;
			PlayerNode current = naqHead;			
			
			@Override
			public boolean hasNext() {
				if(current != null){
					try {
						current.unlock();
					} catch (NodeNotLockedException e) {}
					return (current.nextNaq != null);
				}
				else
					return false;
			}

			@Override
			public PlayerNode next() {
				if(hasNext())
				{
					try {
						if(prev != null)
							prev.unlock();
						prev = current;
						current.nextNaq.lock();
						current = current.nextNaq;
					} catch (NodeNotLockedException e) {
						e.printStackTrace();
					}
					return current;
				}
				else
					return null;
			}

			@Override
			public void remove() {
				if(prev != null && current != null){
					prev.nextNaq = current.nextNaq;
					try {
						current.unlock();
						prev.nextNaq.lock();
						current = prev.nextNaq;
					} catch (NodeNotLockedException e) {
						e.printStackTrace();
					}
				}
			}
		};
	}
	
	public Iterator<PlayerNode> iterateArmy() {
		armyHead.lock();
		return new Iterator<PlayerNode>() {
			PlayerNode prev = null;
			PlayerNode current = armyHead;			
			
			@Override
			public boolean hasNext() {
				if(current != null)
					if(current.nextArmy == null)
					{
						try {
							current.unlock();
							if(prev != null)
								prev.unlock();
						} catch (NodeNotLockedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						return false;
					}
					else
					{
						return true;
					}
					//return (current.nextArmy != null);
				else{
					try {
						current.unlock();
					} catch (NodeNotLockedException e) {
						e.printStackTrace();
					}
					return false;
				}
				/*if(current != null)
					return (current.nextArmy != null);
				else
					return false;*/
			}

			@Override
			public PlayerNode next() {
				if(hasNext())
				{
					try {
						if(prev != null)
							prev.unlock();
						prev = current;
						current.nextArmy.lock();
						current = current.nextArmy;
					} catch (NodeNotLockedException e) {
						e.printStackTrace();
					}
					return current;
				}
				else
					return null;
				/*current = current.nextArmy;
				return current;*/
			}

			@Override
			public void remove() {
				if(prev != null && current != null){
					prev.nextArmy = current.nextArmy;
					try {
						current.unlock();
						prev.nextArmy.lock();
						current = prev.nextArmy;
					} catch (NodeNotLockedException e) {
						e.printStackTrace();
					}
				}
			}			
		};
	}

	@Override
	public Iterator<PlayerNode> iterator() {
		return iterateArmy();
	}
}
